package net.pimpas.visitor;

import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;

import net.pimpas.core.visitor.BaseClassVisitor;
import net.pimpas.core.visitor.BaseDirectoryVisitor;
import net.pimpas.core.visitor.BaseFileVisitor;
import net.pimpas.core.visitor.BasePackageVisitor;
import net.pimpas.core.visitor.ClassVisitor;
import net.pimpas.core.visitor.DirectoryVisitor;
import net.pimpas.core.visitor.FileVisitor;
import net.pimpas.core.visitor.PackageVisitor;
import net.pimpas.core.visitor.Visitor;
import net.pimpas.util.reflection.ReflectionUtils;

import org.apache.log4j.Logger;

public final class FrameworkClassesVisitor extends BaseClassVisitor {
	private static Logger logger = Logger.getLogger(FrameworkClassesVisitor.class);
	private static Collection<Class<? super Visitor>> visitors = new LinkedList<Class<? super Visitor>>();
	
	public FrameworkClassesVisitor() {
		super(false,
				Visitor.class,
				ClassVisitor.class,
				DirectoryVisitor.class,
				FileVisitor.class,
				PackageVisitor.class,
				FrameworkClassesVisitor.class, 
				BaseClassVisitor.class, 
				BaseDirectoryVisitor.class, 
				BaseFileVisitor.class,
				BasePackageVisitor.class);
	}
	
	@Override
	public boolean accept(Class<?> clazz) {
		boolean b =  super.accept(clazz);
		return (b) ? (ReflectionUtils.isSubclass(clazz, Visitor.class)) : b;
	}

	@SuppressWarnings("unchecked")
	@Override
	public void visitClass(Class<?> clazz) {
		logger.debug("{Visitor found in CLASSPATH. Visitor [ "+clazz.getName()+" ] added in visitors list.}");
		visitors.add((Class<? super Visitor>) clazz);
	}
	
	public static Collection<Class<? super Visitor>> getVisitorClasses( ) {
		return Collections.unmodifiableCollection(visitors);
	}
}